Scripting
to do: read-only vars, smething about bindup, example of useful script? Savage Script Basics This is a small document about the Savage Scripting basics. Alright first off the best possible thing to do, as in most things, is to dive in and look at some of the code S2 has made for the game itself. The best way I know of teaching is to do just that, so im going to rip parts of their code out and point out things I think you should know. The basics are pretty easy to grasp so I hope I don?t confuse anyone or myself ;). The script itself is pretty much responsible for all the settings and all the GUI you see in the game. The way levels are made, the way items are created, the way units are made, are all in the script. Some basic commands you should know: *~? - one of the most important commands to know if your making your scripts look nice. This is the line feed call. When the engine 'compiles' your script it will place the next line into the place of this tilde. This is very useful if your making a if case that is very very long. ??? if 3 ?~ show test;~ hide test2; * ; - a command termination symbol is needed for commands executed within quotes, as shown above. This just simply tells the engine that your done with one command and to read the next as a new one. *\ - another very important symbol to know, this separates multiple quotes, # and $s that are contained together. These have to be one of the biggest things that makes s2script so complicated. if test ? goto new; echo \?test\?; show test_#object_\#num\##_obj; *createvar -declares a variable for your scripts (usage : createvar TS_test2 ) *set -Used on a single line to insert a value into your variable (usage: set TS_test 2) - note there is no equal sign *exec -executes a script from within another script, ( the path is from the current director. Function also uses forward slashes '/' and paths can be altered to go down a dir '../' or start from root by using '/'. *@ - creates a point for the goto command *goto - will jump to the minifunction start and skip anything between the goto and the @ *echo - will echo a variable or a string to the console *if 'action' quotes not needed if it's a single action, multiple actions must be in quotes. **The cases are just like C *** ?????? equal to??????????????????????????????????? if 3 goto done ***!=???????? not equal to????????????????????????????? if != 4 goto done ***????????? greater than????????????????????????????? if > 3 goto done ***<=??????? less than or equal????????????????????? if >=3 goto done ***>=??????? greater than or equal???????????????? if <=3 goto done ***|?????????? (dual pipes, no space) OR??????? if 3 || test 2) goto done ***&???????? AND??????????????????????????????????????? if( test 3 && test4 3) goto done ***!?????????? NOT (exclamation point)????????? if( !test) goto done **Cases also require certain 'containers' ***?[ Brackets are required for numbers if test goto done (where test contains a numerical value) *#$ *ask ? ask the engine a question and it will return the answer, the answer will be a Boolean answer in the variable 'answer'. Following is a list of valid 'questions' Most are self explanatory, I have no Idea what X is **stringsMatch **fileExists **currentDir **isResearched **isAvailable **isResearchable **isResearching **hasWeapon **ammo **maxAmmo **isInInventory **inventorySlot **whoIsCommander **playerState **stateIcon **buildItem **selection **objectType **isAlly **isOfficer **X *do -- This will exect a varable as though it were a command, set test set test2 3; echo \test done\ do test would exec whats inside the variable this is VERY useful *inc -- will increase the by amount adds to *toggle -- will toggle a Boolean variable between 0 and 1 if the variable is 0 > its considered to be 1 or TRUE I think that is most of it. Lets get onto some real coded! Ive chose a little tidbit from savage's scripts to code bind #key_chatall# "select endgame_chat_box_panel:endgame_input_textbox; param commit_cmd \"chat #lobby_chat_msg#; select endgame_chat_box_panel:endgame_input_target_label; param text \\\"\\\"; set lobby_chat_msg \\\"\\\"\"; select endgame_chat_box_panel:endgame_input_target_label; param text \"Global->\"; textbox activate endgame_chat_box_panel:endgame_input_textbox" /code Mmm look at that chunk! Confused yet? Lets break this down so you can sorta understand what is really going on in there. This script by the way is the one that puts 'Global->'in the text box when you hit the chat all key. *bind #key_chatall# - this little part calls the bind function, the #key_chatall# calls up the key that chatall is currently bound too *"select endgame_chat_box_panel:endgame_input_textbox; - select is a widget function (will be explained later in my GUI guide) but pretty much lets you select and alter stuff from within it *param commit_cmd \"' .. . . ' sets a param in the widet that was previously selected everything after the \ till you see another \ is contained in the command param *\"chat #lobby_chat_msg#; select endgame_chat_box_panel:endgame_input_target_label; param text \\\"\\\"; set lobby_chat_msg \\\"\\\"\"; now this may look complicated but its pretty simple, everything here is being put in the param commit cmd. It calls up a chat command, selects a widget, and changes the text param in it. Notice the \\\ \\\, this is the same as saying //, wich is Null or blank. The reason it has 3 of the slashes (I think it should only have 2, I think slothy over killed it ;) is because its 2 layers in, you have a /, \/, and now a/ \\\/. The same applies for the set lobby_chat_message. Then the commit_command is closed with a \/; *select endgame_chat_box_panel:endgame_input_target_label; param text \"Global->\"; textbox activate endgame_chat_box_panel:endgame_input_textbox" -- lets take this entire last bit its easy. We select a widget again, and alter it?s text param using \/ again because we left the commit_cmd quotes. We set the text to Global, then active the text box so the user can input data. Quick start # Create file named helloWorld.cfg in game folder. # Edit this file with your favourite editor (I hope its not Word): chat Hello World! # Run game and host new game # Enter in console (~): exec /helloWorld.cfg; or in chatbox /exec /helloWorld.cfg # You should see results ;) Comments To comment code, or to disable some code use # sign as first char in line. # say hello to the world :) #chat Hello World! chat Hello World! Build-in Functions and Variables List of (not all) functions, list of (not all) variables. Custom Variables Variables can be any of these types: * Float * Int * String To create or change variable use set function. Variable name can contain alphanumeric chars and _-. Also be careful to not overwrite build-in variable. set myFavouriteNumber 13 chat My favourite number is #myFavouriteNumber# set myFavouriteNumber 13.31 chat My favourite number is #myFavouriteNumber# set myFavouriteGame "Savage" #quotation is optional here chat My favourite game is #myFavouriteGame# As you can see to display variable value we used double #. Custom Functions Defining function is similar to defining variable. To exec function we use do command. set myFunction "chat one; chat two; chat three;" do myFunction Conditional statements operators available in statements: , <=, >=, !=, &, | set firstNumber 10 if 10 chat true; else chat false; if <= 20 chat true; else chat false; if != 20 chat true; else chat false; set firstNumber 1 set secondNumber 0 if 1 & secondNumber 0 chat true; else chat false; if 0 | secondNumber 0 chat true; else chat false; Be sure not to add extra spaces, for example this code will display false: set firstNumber 1 set secondNumber 0 if 1 & secondNumber 0 chat true; else chat false; Loops To create loop we use for function. for ; set fInLoop "chat ^y#vItem#. SPAM!" createvar vItem for vItem 1 5 1 #fInLoop#; Note that vItem must be created before loop. Ask function Ask is a special function that can give you some interesting info about player. ask value2 Where query is one of: ammo, inventory, stringsMatch (to see the list of all query strings just run ask without parameters). The result of this function will be saved in answer variable. Examples will explain this: # this will display player weapon name (1 - is a inventory slot) ask inventory 1; chat #answer#; ask inventory 1; # stringsMatch query requires 2 parameters ask stringsMatch #answer# human_crossbow; if 1 chat Behold! I have xbow now! Binds Binds are used to assign events to keys. To get names of special keys run listkeys command. bind x "ask inventory 1; ask stringsMatch #answer# human_crossbow; if 1 chat Behold! I have xbow now!;" Category:Tutorials